package aliyun

import (
	"errors"
	"gitee.com/tools/internal/config"
	"gitee.com/tools/internal/domain"
	"gitee.com/tools/internal/service/document"
	openClient "github.com/alibabacloud-go/darabonba-openapi/v2/client"
	"github.com/alibabacloud-go/docmind-api-20220711/client"
	"github.com/alibabacloud-go/tea-utils/v2/service"
	"log"
	"os"
	"time"
)

type AliyunConvert struct {
	endpoint string
}

func NewAliyunConvert() document.Document {
	return &AliyunConvert{
		endpoint: "docmind-api.cn-hangzhou.aliyuncs.com",
	}
}

func (a *AliyunConvert) initClient(filename string) (*client.Client, *os.File, error) {
	cfg, err := a.GetKS(a.endpoint)
	if err != nil {
		return nil, nil, err
	}
	// 初始化client
	cli, err := client.NewClient(&cfg)
	if err != nil {
		return nil, nil, err
	}
	// 上传本地文档调用接口
	file, err := os.Open(filename)
	if err != nil {
		return nil, nil, err
	}
	return cli, file, nil
}

func (a *AliyunConvert) ConvertPdfToWord(filename string) (domain.RequestData, error) {
	cli, file, err := a.initClient(filename)
	if err != nil {
		return domain.RequestData{}, err
	}

	// 初始化接口request
	request := client.SubmitConvertPdfToWordJobAdvanceRequest{
		FileName:      &filename,
		FileUrlObject: file,
	}
	// 创建RuntimeObject实例并设置运行参数
	options := service.RuntimeOptions{}
	response, err := cli.SubmitConvertPdfToWordJobAdvance(&request, &options)
	if err != nil {
		return domain.RequestData{}, err
	}
	// 打印结果
	respId := *response.Body.Data.Id
	if respId == "" {
		log.Println("未获取到请求ID")
		return domain.RequestData{}, errors.New("请求失败，请检查原因")
	}

	var reqData domain.RequestData
	if *response.Body.Data.Id != "" {
		reqData.Id = *response.Body.Data.Id
		reqData.RequestId = *response.Body.RequestId
	} else {
		reqData.Id = *response.Body.Data.Id
		reqData.RequestId = *response.Body.RequestId
		reqData.Message = *response.Body.Message
		reqData.Code = *response.Body.Code
	}
	return reqData, nil
}

func (a *AliyunConvert) ConvertPdfToExcel(filename string) (domain.RequestData, error) {
	cli, file, err := a.initClient(filename)
	if err != nil {
		return domain.RequestData{}, err
	}

	// 初始化接口request
	request := client.SubmitConvertPdfToExcelJobAdvanceRequest{
		FileName:      &filename,
		FileUrlObject: file,
	}
	// 创建RuntimeObject实例并设置运行参数
	options := service.RuntimeOptions{}
	response, err := cli.SubmitConvertPdfToExcelJobAdvance(&request, &options)
	if err != nil {
		return domain.RequestData{}, err
	}
	// 打印结果
	respId := *response.Body.Data.Id
	if respId == "" {
		log.Println("未获取到请求ID")
		return domain.RequestData{}, errors.New("请求失败，请检查原因")
	}

	var reqData domain.RequestData
	if *response.Body.Data.Id != "" {
		reqData.Id = *response.Body.Data.Id
		reqData.RequestId = *response.Body.RequestId
	} else {
		reqData.Id = *response.Body.Data.Id
		reqData.RequestId = *response.Body.RequestId
		reqData.Message = *response.Body.Message
		reqData.Code = *response.Body.Code
	}
	return reqData, nil
}

func (a *AliyunConvert) ConvertPdfToImage(filename string) (domain.RequestData, error) {
	cli, file, err := a.initClient(filename)
	if err != nil {
		return domain.RequestData{}, err
	}
	// 初始化接口request
	request := client.SubmitConvertPdfToImageJobAdvanceRequest{
		FileName:      &filename,
		FileUrlObject: file,
	}
	// 创建RuntimeObject实例并设置运行参数
	options := service.RuntimeOptions{}
	response, err := cli.SubmitConvertPdfToImageJobAdvance(&request, &options)
	if err != nil {
		return domain.RequestData{}, err
	}
	respId := *response.Body.Data.Id
	if respId == "" {
		log.Println("未获取到请求ID")
		return domain.RequestData{}, errors.New("请求失败，请检查原因")
	}
	var reqData domain.RequestData
	if *response.Body.Data.Id != "" {
		reqData.Id = *response.Body.Data.Id
		reqData.RequestId = *response.Body.RequestId
	} else {

		reqData.Id = *response.Body.Data.Id
		reqData.RequestId = *response.Body.RequestId
		reqData.Message = *response.Body.Message
		reqData.Code = *response.Body.Code
	}
	return reqData, nil
}
func (a *AliyunConvert) initCli() (*client.Client, error) {
	cfg, err := a.GetKS(a.endpoint)
	if err != nil {
		return nil, err
	}
	// 初始化client
	cli, err := client.NewClient(&cfg)
	if err != nil {
		return nil, err
	}
	return cli, nil
}

// ConvertImageToWord todo
func (a *AliyunConvert) ConvertImageToWord(imageType string, filename ...string) (domain.RequestData, error) {
	cli, err := a.initCli()
	if err != nil {
		return domain.RequestData{}, err
	}
	filesName := []*string{}
	for _, v := range filename {
		filesName = append(filesName, &v)
	}
	// 初始化接口request(这里的图片路径有问题，需要上传到oss或者服务器的在线地址)
	request := client.SubmitConvertImageToWordJobRequest{
		ImageUrls:          filesName,
		ImageNameExtension: &imageType,
	}

	response, err := cli.SubmitConvertImageToWordJob(&request)
	if err != nil {
		return domain.RequestData{}, err
	}
	respId := *response.Body.Data.Id
	if respId == "" {
		log.Println("未获取到请求ID")
		return domain.RequestData{}, errors.New("请求失败，请检查原因")
	}
	var reqData domain.RequestData
	if *response.Body.Data.Id != "" {
		reqData.Id = *response.Body.Data.Id
		reqData.RequestId = *response.Body.RequestId
	} else {

		reqData.Id = *response.Body.Data.Id
		reqData.RequestId = *response.Body.RequestId
		reqData.Message = *response.Body.Message
		reqData.Code = *response.Body.Code
	}
	return reqData, nil
}

func (a *AliyunConvert) ConvertImageToExcel(imageType string, filename ...string) (domain.RequestData, error) {
	cli, err := a.initCli()
	if err != nil {
		return domain.RequestData{}, err
	}
	filesName := []*string{}
	for _, v := range filename {
		filesName = append(filesName, &v)
	}
	// 初始化接口request
	request := client.SubmitConvertImageToExcelJobRequest{
		ImageUrls:          filesName,
		ImageNameExtension: &imageType,
	}
	response, err := cli.SubmitConvertImageToExcelJob(&request)
	if err != nil {
		return domain.RequestData{}, err
	}
	respId := *response.Body.Data.Id
	if respId == "" {
		log.Println("未获取到请求ID")
		return domain.RequestData{}, errors.New("请求失败，请检查原因")
	}
	var reqData domain.RequestData
	if *response.Body.Data.Id != "" {
		reqData.Id = *response.Body.Data.Id
		reqData.RequestId = *response.Body.RequestId
	} else {

		reqData.Id = *response.Body.Data.Id
		reqData.RequestId = *response.Body.RequestId
		reqData.Message = *response.Body.Message
		reqData.Code = *response.Body.Code
	}
	return reqData, nil
}

func (a *AliyunConvert) ConvertImageToPdf(imageType string, filename ...string) (domain.RequestData, error) {
	cli, err := a.initCli()
	if err != nil {
		return domain.RequestData{}, err
	}
	filesName := []*string{}
	for _, v := range filename {
		filesName = append(filesName, &v)
	}
	// 初始化接口request
	request := client.SubmitConvertImageToPdfJobRequest{
		ImageUrls:          filesName,
		ImageNameExtension: &imageType,
	}
	response, err := cli.SubmitConvertImageToPdfJob(&request)
	if err != nil {
		return domain.RequestData{}, err
	}
	respId := *response.Body.Data.Id
	if respId == "" {
		log.Println("未获取到请求ID")
		return domain.RequestData{}, errors.New("请求失败，请检查原因")
	}
	var reqData domain.RequestData
	if *response.Body.Data.Id != "" {
		reqData.Id = *response.Body.Data.Id
		reqData.RequestId = *response.Body.RequestId
	} else {

		reqData.Id = *response.Body.Data.Id
		reqData.RequestId = *response.Body.RequestId
		reqData.Message = *response.Body.Message
		reqData.Code = *response.Body.Code
	}
	return reqData, nil
}

func (a *AliyunConvert) GetConvertResult(id string) (domain.File, error) {
	// 查询
	cfg, err := a.GetKS(a.endpoint)
	if err != nil {
		return domain.File{}, err
	}
	cli, err := client.NewClient(&cfg)
	if err != nil {
		return domain.File{}, err
	}

	req := client.GetDocumentConvertResultRequest{Id: &id}
	res, err := cli.GetDocumentConvertResult(&req)
	if err != nil {
		return domain.File{}, err
	}
	// todo 暂时放这里
	const bizSize = 3
	if *res.Body.Status != "Success" {
		for _ = range bizSize {
			time.Sleep(1000 * time.Millisecond)
			res, err = cli.GetDocumentConvertResult(&req)
			if err != nil {
				return domain.File{}, err
			}
			if *res.Body.Status == "Success" {
				break
			}
		}
	}
	var resp = domain.File{
		Status:    *res.Body.Status,
		RequestId: *res.Body.RequestId,
		Completed: *res.Body.Completed,
		Data:      res.Body.Data,
	}
	return resp, nil
}

func (a *AliyunConvert) GetKS(endpoint string) (openClient.Config, error) {
	credential, err := config.GetKS()
	log.Println(credential)
	if err != nil {
		return openClient.Config{}, err
	}
	// 通过credentials获取配置中的AccessKey ID
	accessKeyId, err := credential.GetAccessKeyId()
	if err != nil {
		return openClient.Config{}, err
	}
	// 通过credentials获取配置中的AccessKey Secret
	accessKeySecret, err := credential.GetAccessKeySecret()
	if err != nil {
		return openClient.Config{}, err
	}

	cfg := openClient.Config{
		AccessKeyId:     accessKeyId,
		AccessKeySecret: accessKeySecret,
		Endpoint:        &endpoint,
	}
	return cfg, nil
}
